package com.onlyxiahui.aware.basic.util.work.task;

import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.ExecutorService;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.onlyxiahui.common.utils.base.util.thread.ThreadPoolBuilder;


/**
 * 
 * Description <br>
 * Date 2019-04-27 08:26:39<br>
 * 
 * @author XiaHui [onlovexiahui@qq.com]<br>
 * @since 1.0.0
 */
public class TaskThreadQueue extends Thread {
	protected final Logger logger = LoggerFactory.getLogger(getClass());

	/**
	 * cpu的数量
	 */
	private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors();
	/**
	 * 核心线程数 = CPU核心数 + 1
	 */
	private static final int CORE_POOL_SIZE = CPU_COUNT + 1;
	/**
	 * 线程池最大线程数 = CPU核心数 * 2 + 1
	 */
	private static final int MAXIMUM_POOL_SIZE = CPU_COUNT * 2 + 1;
	/**
	 * 非核心线程闲置时超时1s
	 */
	private static final long KEEP_ALIVE = 1000;

	private ConcurrentLinkedQueue<TaskExecute> executeTaskQueue = new ConcurrentLinkedQueue<TaskExecute>();// 任务队列
	private long sleepTime = 200;// 线程休眠时间
	private ExecutorService pool = null;;

	public TaskThreadQueue() {
		this(CORE_POOL_SIZE, MAXIMUM_POOL_SIZE);
	}

	public TaskThreadQueue(int size) {
		this(size, size);
	}

	public TaskThreadQueue(int coreSize, int maxSize) {
		// pool = Executors.newFixedThreadPool(poolCount);
		pool = ThreadPoolBuilder.build(coreSize, maxSize, KEEP_ALIVE);
		this.start();
	}

	/**
	 * 添加任务
	 * 
	 * @param executeTask
	 */
	public void add(TaskExecute executeTask) {
		executeTaskQueue.add(executeTask);
	}

	@Override
	public void run() {
		while (true) {
			handleTask();// 处理任务
			threadSleep(sleepTime);
		}
	}

	private void threadSleep(long time) {
		try {
			sleep(time);
		} catch (InterruptedException e) {
			logger.error("", e);
		}
	}

	/**
	 * 处理任务队列，检查其中是否有任务
	 */
	private void handleTask() {
		TaskExecute executeTask;
		while (executeTaskQueue.peek() != null) {
			executeTask = executeTaskQueue.poll();
			try {
				handleTask(executeTask);
			} catch (Exception e) {
				logger.error("", e);
			}
		}
	}

	/**
	 * 执行任务操作
	 * 
	 * @param executeTask
	 */
	private void handleTask(TaskExecute executeTask) {
		pool.execute(new ExecuteRunnable(executeTask));
	}

	class ExecuteRunnable implements Runnable {
		TaskExecute executeTask;

		ExecuteRunnable(TaskExecute executeTask) {
			this.executeTask = executeTask;
		}

		@Override
		public void run() {
			try {
				executeTask.execute();
			} catch (Exception e) {
				logger.error("", e);
			}
		}
	}
}
